package cn.lili.modules.order.order.entity.dos;

import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.modules.order.order.entity.dto.CurrentRefundPriceDTO;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.enums.OrderFlowStatusEnum;
import cn.lili.modules.order.order.entity.enums.ProfitSharingStatusEnum;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.mybatis.model.BaseEntity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serial;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 商家订单流水
 *
 * @author Chopper
 * @since 2020/11/17 7:31 下午
 */
@Data
@TableName("li_order_flow")
@ApiModel(value = "订单流水")
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class OrderFlow extends BaseEntity {

    @Serial
    private static final long serialVersionUID = -5998757398902747939L;

    @ApiModelProperty(value = "流水编号")
    private String sn;

    @ApiModelProperty(value = "流水金额")
    private Double flowPrice;

    @ApiModelProperty(value = "退款金额")
    private Double refundPrice;

    @ApiModelProperty(value = "是否付款，true为已付款")
    private Boolean isPay;
    @ApiModelProperty(value = "是否全部退款，true为全部退款")
    private Boolean fullRefund;

    @ApiModelProperty(value = "订单sn")
    private String orderSn;

    /**
     * @see PaymentMethodEnum
     */
    @ApiModelProperty(value = "支付方式名称")
    private String paymentMethod;


    @ApiModelProperty(value = "第三方交易流水号")
    private String transactionId;


    @CreatedDate
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT)
    @ApiModelProperty(value = "创建时间", hidden = true)
    private Date createTime;


    @ApiModelProperty(value = "会员id")
    private String memberId;

    @ApiModelProperty(value = "会员名称")
    private String nickname;

    @ApiModelProperty(value = "平台商户id")
    private String platformMchid;


    @ApiModelProperty(value = "店铺ID")
    private String storeId;
    @ApiModelProperty(value = "店铺名称")
    private String storeName;

    @ApiModelProperty(value = "店铺子商户ID")
    private String storeSubMchid;

    @ApiModelProperty(value = "供应商标识")
    private String supplierId;
    @ApiModelProperty(value = "供应商名称")
    private String supplierName;

    @ApiModelProperty(value = "供应商子商户ID")
    private String supplierSubMchid;

    @ApiModelProperty(value = "分销商标识")
    private String distributionId;

    @ApiModelProperty(value = "分销商标识")
    private String distributionName;

    @ApiModelProperty(value = "分销商子商户ID")
    private String distributorSubMchid;

    //============================================profitsharing================================================

    @ApiModelProperty(value = "店铺结算金额")
    private Double sellerSettlementPrice = 0D;
    @ApiModelProperty(value = "供应商结算金额")
    private Double supplierSettlementPrice = 0D;
    @ApiModelProperty(value = "分销佣金")
    private Double distributionSettlementPrice = 0D;
    @ApiModelProperty(value = "平台盈利金额=实际支付金额(flowPrice)-商家结算金额(sellerSettlementPrice)-供应商结算金额(supplierSettlementPrice)")
    private Double platformSettlementPrice = 0D;


    //============================================end profitsharing================================================

    @ApiModelProperty(value = "流水详情")
    private String priceDetail;
    //用户支付金额=平台佣金+供应商金额+店铺金额+分销佣金


    @ApiModelProperty(value = "店铺核验状态")
    private Boolean storeVerify = true;

    @ApiModelProperty(value = "供应商核验状态")
    private Boolean supplierVerify = true;

    @ApiModelProperty(value = "平台核验状态")
    private Boolean platformVerify = true;

    @ApiModelProperty(value = "是否为特殊订单：特殊订单为某一端结算金额为负数，那么付款目标转向平台子商户，然后分账统一从平台余额中提取")
    private Boolean specialOrder;


    @ApiModelProperty(value = "店铺补交差额流水号")
    private String storeOutTradeNo;

    @ApiModelProperty(value = "供应商补交差额流水号")
    private String supplierOutTradeNo;

    @ApiModelProperty(value = "平台补交差额流水号")
    private String platformOutTradeNo;

    /**
     * @see OrderFlowStatusEnum
     */
    @ApiModelProperty(value = "审核状态")
    private String orderFlowStatus = OrderFlowStatusEnum.PASS.name();

    /**
     * @see cn.lili.modules.order.order.entity.enums.ProfitSharingStatusEnum
     */
    @ApiModelProperty(value = "分账状态")
    private String profitSharing;

    @ApiModelProperty(value = "分账错误消息")
    private String errorMsg;

    @ApiModelProperty(value = "城市站点ID-订单地址")
    private String urbanIdByAddress;

    @ApiModelProperty(value = "城市站点ID-供应商")
    private String urbanIdBySupplier;

    @ApiModelProperty(value = "城市站点名称-订单地址")
    private String urbanNameByAddress;

    @ApiModelProperty(value = "城市站点名称-供应商")
    private String urbanNameBySupplier;

    @ApiModelProperty(value = "城市站点核验状态")
    private Boolean urbanVerify = true;

    @ApiModelProperty(value = "是否有异常流水审核权限：订单地址所属城市分站没有审核权限，供应商所属城市分站有审核权限")
    @TableField(exist = false)
    private boolean applyFlag;

    @ApiModelProperty(value = "店铺获得的绿色积分分佣")
    private Double storeGreenScore = 0D;

    @ApiModelProperty(value = "供应商获得的绿色积分分佣")
    private Double supplierGreenScore = 0D;

    @ApiModelProperty(value = "用户获得的绿色积分分佣")
    private Double memberGreenScore = 0D;

    @ApiModelProperty(value = "城市站点获得的绿色积分分佣")
    private Double siteGreenScore = 0D;

    @ApiModelProperty(value = "订单地址所在城市站点获得的绿色积分分佣")
    private Double siteAddressGreenScore = 0D;

    @ApiModelProperty(value = "公益投放获得的绿色积分分佣")
    private Double greenCommonwealGreenScore = 0D;

    @ApiModelProperty(value = "总共可分佣绿色积分")
    private Double greenScore = 0D;

    @ApiModelProperty(value = "F分分配值")
    private Double fmoney;

    @ApiModelProperty("佣金收益:店主直推佣金 + 店主间推佣金 之和")
    @TableField(exist = false)
    private Double totalCommiss;

    @ApiModelProperty(value = "工会绿色积分分佣")
    private Double unionGreenScore = 0D;

    @ApiModelProperty(value = "城主绿色积分分佣")
    private Double castellanGreenScore = 0D;

    @ApiModelProperty(value = "上推佣金（店主-下级用户订单分佣）")
    private Double lowerCommiss = 0D;

    @ApiModelProperty(value = "间推佣金（店主-间推用户订单分佣）")
    private Double lowerSubCommiss = 0D;

    @ApiModelProperty(value = "第三方交易流水号")
    private String settlementStatus;

    /**
     * 直推店主用户ID
     * */
    private String lowerCommissId;

    /**
     * 当前用户身份
     */
    private Boolean isDistribution;

    /**
     * 间推店主用户ID
     * */
    private String lowerSubCommissId;

    @TableField(exist = false)
    private String month;

    @TableField(exist = false)
    private String areaId;

    @TableField(exist = false)
    private String goodsId;

    @TableField(exist = false)
    private String goodsName;

    @ApiModelProperty("城主收益发放状态: 城主收益发放状态：1, 结算中 2 , 已发放")
    private Integer commissStatus;

    @ApiModelProperty("城主收益发放时间")
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date commissGiveTime;

    @ApiModelProperty("工会收益发放状态：1, 结算中 2 , 已发放")
    private Integer unionCommissStatus;

    @ApiModelProperty("工会收益发放时间")
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date unionCommissGiveTime;

    @ApiModelProperty("工会收益发放类型：1, 贡献值 2 , 绿色积分")
    private Integer unionCommissType;

    @TableField(exist = false)
    private String unionId;

    @TableField(exist = false)
    private String ocUserId;

    /**
     * 校验结果，如果三个都为true，则可以发货操作，否则需要手动审核操作才可以
     *
     * @return 校验结果
     */
    public Boolean verify() {
        return this.storeVerify && this.supplierVerify && this.platformVerify && this.urbanVerify;
    }

    /**
     * 校验消息
     *
     * @return 校验消息
     */
    public String verifyMessage() {
        StringBuilder sb = new StringBuilder();
        sb.append("订单编号{").append(this.orderSn).append("}");
        if (Boolean.FALSE.equals(this.storeVerify)) {
            sb.append("异常订单需店铺手动审核。");
        }
        if (Boolean.FALSE.equals(this.supplierVerify)) {
            sb.append("异常订单需供应商手动审核。");
        }
        if (Boolean.FALSE.equals(this.urbanVerify)) {
            sb.append("异常订单需城市分站手动审核。");
        }
        if (Boolean.FALSE.equals(this.platformVerify)) {
            sb.append("异常订单需平台手动审核。");
        }
        return sb.toString();
    }

    /**
     * 构造方法
     *
     * @param order 订单
     */
    public OrderFlow(Order order) {

        //去掉时间。
        this.setRefundPrice(0D);
        this.setFullRefund(false);
        this.setIsPay(true);
        this.setFmoney(PriceDetailDTO.getModel(order.getPriceDetail()).getFmoney());

        this.setProfitSharing(ProfitSharingStatusEnum.WAIT_COMPLETE.name());

        //入账
        this.setSn(SnowFlake.createStr("OF"));

        this.setStoreId(order.getStoreId());
        this.setDistributionId(order.getDistributionId());
        this.setDistributionName(order.getDistributionName());
        this.setStoreName(order.getStoreName());
        this.setMemberId(order.getBuyerId());
        this.setNickname(order.getNickname());
        //添加支付方式
        this.setPaymentMethod(order.getPaymentMethod());
        //添加第三方支付流水号
        this.setTransactionId(order.getOutTradeNo());
        this.setOrderSn(order.getSn());

        this.setSupplierName(order.getSupplierName());
        this.setSupplierId(order.getSupplierId());
        this.setSettlementStatus(order.getOrderStatus());

        //获取金额详情
        PriceDetailDTO priceDetailDTO = PriceDetailDTO.getModel(order.getPriceDetail());

        if (priceDetailDTO != null) {
            this.setFlowPrice(priceDetailDTO.getFlowPrice());
            this.setSupplierSettlementPrice(priceDetailDTO.getSupplierSettlementPrice());
            this.setSellerSettlementPrice(priceDetailDTO.getSellerSettlementPrice());
            this.setDistributionSettlementPrice(priceDetailDTO.getDistributorSettlementPrice());

            this.setGreenScore(priceDetailDTO.getGreenScore());

            this.setPlatformSettlementPrice(priceDetailDTO.getPlatformSettlementPrice());

            // 绿色积分分佣计算
            this.setSiteAddressGreenScore(priceDetailDTO.getSiteAddressGreenScore());
            this.setSiteGreenScore(priceDetailDTO.getSiteGreenScore());
            this.setUnionGreenScore(priceDetailDTO.getUnionGreenScore());
            this.setCastellanGreenScore(priceDetailDTO.getCastellanGreenScore());
            this.setLowerCommiss(priceDetailDTO.getLowerGreenScore());
            this.setLowerSubCommiss(priceDetailDTO.getLowerSubGreenScore());
            this.setStoreGreenScore(priceDetailDTO.getStoreGreenScore());
            this.setMemberGreenScore(priceDetailDTO.getMemberGreenScore());
            this.setGreenCommonwealGreenScore(priceDetailDTO.getGreenCommonwealGreenScore());

            if (priceDetailDTO.getPlatformSettlementPrice() < 0) {
                this.setPlatformVerify(false);
            }
            if (priceDetailDTO.getSellerSettlementPrice() < 0) {
                this.setStoreVerify(false);
            }
            if (priceDetailDTO.getSupplierSettlementPrice() < 0) {
                this.setSupplierVerify(false);
                this.setUrbanVerify(false);
            }

            //如果有一个为false，则需要手动审核
            if (Boolean.TRUE.equals(!this.platformVerify || !this.supplierVerify || !this.storeVerify || !this.urbanVerify)) {
                this.setOrderFlowStatus(OrderFlowStatusEnum.AUDIT.name());
                this.setSpecialOrder(true);
            }

            this.setUrbanIdByAddress(order.getUrbanIdByAddress());
            this.setUrbanIdBySupplier(order.getUrbanIdBySupplier());

            this.setPriceDetail(priceDetailDTO.toJson());
        } else {
            throw new ServiceException("订单流水金额详情为空");
        }

        if(CharSequenceUtil.isEmpty(this.getDistributionId())) {
            this.distributionSettlementPrice = 0D;
        }

        if(CharSequenceUtil.isEmpty(this.getStoreId())) {
            this.storeGreenScore = 0D;
        }

        if(CharSequenceUtil.isEmpty(this.getSupplierId()) || this.getSupplierId().equals("-1")) {
            this.supplierGreenScore = 0D;
        }

        if(CharSequenceUtil.isEmpty(this.getUrbanIdBySupplier())) {
            this.siteGreenScore = 0D;
        }

        if(CharSequenceUtil.isEmpty(this.getUrbanIdByAddress())) {
            this.siteAddressGreenScore = 0D;
        }

        //店主关系
        this.lowerCommissId = order.getLowerCommissId();
        this.lowerSubCommissId = order.getLowerSubCommissId();
        this.isDistribution = order.getIsDistribution();
    }


    /**
     * 全额退款
     *
     * @param refundPrice 退款金额
     */
    public void appendRefundPrice(Double refundPrice) {
        this.setRefundPrice(CurrencyUtil.add(this.getRefundPrice(), refundPrice));
        if (this.getRefundPrice() >= (this.getFlowPrice())) {
            this.setFullRefund(true);
            this.setProfitSharing(ProfitSharingStatusEnum.ORDER_CANCEL.name());
            this.sellerSettlementPrice = 0D;
            this.supplierSettlementPrice = 0D;
            this.distributionSettlementPrice = 0d;
            this.platformSettlementPrice = 0d;
        }
    }

    /**
     * 部分退款
     *
     * @param currentRefundPriceDTO 退款金额DTO
     */
    public void appendRefundPrice(CurrentRefundPriceDTO currentRefundPriceDTO) {

        this.appendRefundPrice(currentRefundPriceDTO.getTotalRefundPrice());

        this.reduceDistributionPrice(currentRefundPriceDTO.getDistributionRefundPrice());
        this.reducePlatformPrice(currentRefundPriceDTO.getPlatformRefundPrice());
        this.reduceSellerPrice(currentRefundPriceDTO.getSellerRefundPrice());
        this.reduceSupplierPrice(currentRefundPriceDTO.getSupplierRefundPrice());


    }

    public void reducePlatformPrice(Double price) {
        if (price == null || this.getPlatformSettlementPrice() == 0) {
            return;
        }
        this.setPlatformSettlementPrice(CurrencyUtil.sub(this.getPlatformSettlementPrice(), price));
    }


    public void reduceSupplierPrice(Double price) {
        if (price == null || this.getPlatformSettlementPrice() == 0) {
            return;
        }
        this.setSupplierSettlementPrice(CurrencyUtil.sub(this.getSupplierSettlementPrice(), price));
    }


    public void reduceSellerPrice(Double price) {
        if (price == null || this.getPlatformSettlementPrice() == 0) {
            return;
        }
        this.setSellerSettlementPrice(CurrencyUtil.sub(this.getSellerSettlementPrice(), price));
    }


    public void reduceDistributionPrice(Double price) {
        if (price == null || this.getDistributionSettlementPrice() == 0) {
            return;
        }
        this.setDistributionSettlementPrice(CurrencyUtil.sub(this.getDistributionSettlementPrice(), price));
    }


    public Double getSellerSettlementPrice() {
        if (sellerSettlementPrice == null) {
            return 0D;
        }
        return sellerSettlementPrice;
    }

    public Double getSupplierSettlementPrice() {
        if (supplierSettlementPrice == null) {
            return 0D;
        }
        return supplierSettlementPrice;
    }

    public Double getDistributionSettlementPrice() {
        if (distributionSettlementPrice == null) {
            return 0D;
        }
        return distributionSettlementPrice;
    }

    public Double getPlatformSettlementPrice() {
        if (platformSettlementPrice == null) {
            return 0D;
        }
        return platformSettlementPrice;
    }

    public Double getRefundPrice() {
        if (refundPrice == null) {
            return 0D;
        }
        return refundPrice;
    }


}